package com.chen.base.module.mybatis.utils;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chen.base.utils.SpringContextHolder;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;

/**
 * 分页相关工具类
 * @author: ChenJinLong
 * @DATE: 2024/5/14
 **/
public class PageUtil {

    /**
     * 分页遍历数据
     * @param mapper mapper
     * @param queryWrapper 查询条件
     * @param consumer 数据消费
     * @param <T> 数据类型
     */
    public static <T> void pageData(BaseMapper<T> mapper, Wrapper<T> queryWrapper, Consumer<T> consumer){
        pageData(mapper, queryWrapper, -1, consumer);
    }

    /**
     * 分页遍历数据
     * @param mapper mapper
     * @param queryWrapper 查询条件
     * @param pageLimit 在某页停止分页遍历, -1表示不限制, 直到查询完数据为止
     * @param consumer 数据消费
     * @param <T> 数据类型
     */
    public static <T> void pageData(BaseMapper<T> mapper, Wrapper<T> queryWrapper,
                                    int pageLimit, Consumer<T> consumer){
        ThreadPoolTaskExecutor executor = SpringContextHolder.getBean("commonThreadPoolExecutor");
        int current = 1;
        while (current != -1){
            // 分页查询
            Page<T> page = mapper.selectPage(new Page<>(current, 500), queryWrapper);
            List<T> list = page.getRecords();
            if (CollectionUtil.isNotEmpty(list)){
                // 异步遍历数据
                CompletableFuture.runAsync(() -> {
                    for (T t : list) {
                        consumer.accept(t);
                    }
                }, executor);
            }
            // 页数加1, 如果没有下一页, 则为-1, 结束循环
            current = page.hasNext() ? current + 1 : -1;
            if (pageLimit != -1 && current >= pageLimit){
                break;
            }
        }
    }

    /**
     * 根据mysql limit 分页的偏移量参数，计算出统一的分页参数
     * @param offset 偏移量
     * @param pageSize 页大小
     * @return 当前页
     */
    public static int getCurrPage(int offset, int pageSize){
        return (offset / pageSize) + 1;
    }
}
